package cn.felord.current;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * The type Thread learning.
 *
 * @author Dax
 * @since 9 :11  2018/7/17
 */
public class ThreadLearning {

    /**
     * 多线程方式一.
     */
    public void typeOne() {
        Runnable run = () -> System.out.println("i am a thread");
        Thread thread = new Thread(run);
//        加入等待CPU进程调度就绪状态
        thread.start();
    }

    /**
     * 多线程方式二.
     */
    public void typeTwo() {
        Thread thread = new Thread();
        //        加入等待CPU进程调度就绪状态
        thread.start();
    }

    /**
     * 多线程方式三.
     */
    public void TypeThree() {
//        实现callable 接口   callable 接口 可以抛出异常   可以有返回值   区别于 方法 一 二
        Callable<Integer> callable = () -> 0;
//        注入任务
        FutureTask<Integer> result = new FutureTask<>(callable);
        Thread thread = new Thread(result);
//        加入等待CPU进程调度就绪状态
        thread.start();

        try {
//            FutureTask 可用于 闭锁 类似于CountDownLatch的作用，在所有的线程没有执行完成之后这里是不会执行的
            Integer integer = result.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

    /**
     * Thread 类分析.
     */
    public void threadStatics() {
        //         匿名线程
        Thread thread = new Thread();
        //          实名线程
        Thread thread1 = new Thread("task");

        // 线程目标代理
        Runnable runnable = () -> {

        };
        Thread thread2 = new Thread(runnable);
//         线程组
        ThreadGroup group = new ThreadGroup("group");
        Thread thread3 = new Thread(group, runnable, "groupThread", 10);
        /*
         * init(ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc, boolean inheritThreadLocals)
         * 所有的构造都有init 方法来实现  线程就绪  可以被cpu 调度    如果执行此方法  run()  不会被线程执行
         *
         */
        thread.start();

        /*
         * 在一个线程调用另一个实例的 interrupt() 方法  不会立即中断线程
         * 只会给该线程设置一个为true 的中断标识  如果 该线程为非阻塞状态 仅仅是设置了中断标识为true
         * 如果是wait、sleep以及jion三个方法引起的阻塞，那么会将线程的中断标志重新设置为false，并抛出一个InterruptedException；
         *
         * 如果是java.nio.channels.InterruptibleChannel进行的io操作引起的阻塞，则会对线程抛出一个ClosedByInterruptedException；
         * 如果是轮询（java.nio.channels.Selectors）引起的线程阻塞，则立即返回，不会抛出异常。
         */
        thread.interrupt();
//     不清除中断状态   只是保证 该线程是否是设置了  interrupted 状态  用来判断当前线程的中断状态(true or false)  并不能证明该线程是否中断
        boolean interrupted = thread.isInterrupted();
//           查看源码后 相当于 Thread.currentThread().isInterrupted(true)  清除中断状态
        boolean interrupted1 = Thread.interrupted();

    }

    public static void main(String[] args) {

        MyThread thread = new MyThread("RUN");
        thread.start();

        try {
            System.out.println(Thread.currentThread().getName());
            /*
             * main 线程 休眠10秒  让出线程  此时只有 RUN 线程在跑   RUN线程的
             */
            Thread.sleep(10000L);
            System.out.println("----------------");
            thread.interrupt();
            System.out.println(" RUN isInterrupted :" + thread.isInterrupted());

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
